package com.common.excel.service.impl;


import com.common.excel.entity.SysTask;
import com.common.excel.enums.UploadStatusEnum;
import com.common.excel.mapper.SysTaskMapper;
import com.common.excel.service.UploadService;
import com.google.common.collect.Lists;
import com.hqd.common.annotation.ExcelField;
import com.hqd.common.utils.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.lang.reflect.Field;
import java.util.List;

@Service
public class UploadServiceImpl implements UploadService {

    private SysTaskMapper sysTaskMapper;

    @Value("${upload.dir}")
    private String fileDir;

    @Value("${upload.url}")
    private String fileUrl;

    @Async
    @Override
    @Transactional
    public <T> void UploadExcel(Class<T> cls, MultipartFile file, String productSource) {
        long startTime=System.currentTimeMillis();   //获取开始时间
        List<T> errorList = Lists.newArrayList();//错误数据集合
        List<T> successList = Lists.newArrayList();//正确数据集合
        List<Integer> errorIndex = Lists.newArrayList();//错误行数
        List<String> msgList = Lists.newArrayList();//错误信息
        Workbook wb = VailVersion.uploadFile(file);//验证EXCEL版本
        if (wb != null) {
            Sheet sheet = wb.getSheetAt(0);
            if(sheet!=null) {
                for (int i = 1; i <= sheet.getLastRowNum(); i++) {
                    Row row = sheet.getRow(i);
                    T e = ExcelUtils.getNewInstance(cls);//新实例
                    // Get annotation field
                    Field[] fs = cls.getDeclaredFields();
                    boolean isSuccess = true;
                    for (Field f : fs){
                        //获取字段上加的@Excel注解
                        ExcelField ef = f.getAnnotation(ExcelField.class);
                        if (ef != null){
                            try {
                                String rowValue = StringUtils.defaultIfBlank(ExcelUtils.getCellValue(row.getCell(ef.sort()))," ");
                                if(ef.require() && StringUtils.isBlank(rowValue)){
                                    msgList.add("第" + i+ "行,"+ef.title()+"字段不能为空");
                                    isSuccess = false;
                                    continue;
                                }
                                //处理每行每列数据
                                Object value = ExcelUtils.getValue(f, row.getCell(ef.sort()),ef.type(),ef.dateType());
                                f.setAccessible(true);
                                if("error".equals(value)){
                                    msgList.add("第" + i+ "行,"+ef.title()+"格式不正确");
                                    isSuccess = false;
                                    f.set(e,rowValue);
                                }else {
                                    f.set(e, value);
                                }
                            }catch (Exception ex){
                                ex.printStackTrace();
                            }
                        }
                    }
                    if(isSuccess) {
                        successList.add(e);
                        errorIndex.add(i);
                    }
                }
            }
        }

        String filePath = UploadFileUtil.uploadFile(file, fileDir, fileUrl);
        SysTask sysTask = new SysTask();
        if(!msgList.isEmpty()){
            //处理错误数据
            String errorPath = UploadFileUtil.removeRow(filePath, errorIndex);
            sysTask.setErrorPath(errorPath);
        }
        long endTime=System.currentTimeMillis(); //获取结束时间
        long consumeTime = (endTime - startTime) / 1000;//执行时间
        long fileSize = file.getSize();//文件大小
        String fileName = file.getOriginalFilename();//文件名称

        sysTask.setId(UIDUtil.generate());
        sysTask.setFileName(fileName);
        sysTask.setFileSize(fileSize);
        sysTask.setConsumeTime(consumeTime);
        sysTask.setSuccessNum(successList.size());
        sysTask.setErrorNum(errorList.size());
        sysTask.setErrorContent(JsonUtils.toJSONNoFeatures(msgList));
        sysTask.setFilePath(filePath);
        sysTask.setUploadStatus(UploadStatusEnum.PROCESSING.getCode());
        sysTask.setProductSource(productSource);
        sysTaskMapper.insert(sysTask);
    }

}
